import { Injectable, InjectByName, InjectFactory, TFactory } from '../../decorators/inject';
import { NTableEvent } from '../../types/cors';
import { ActualValue} from './types';
import { ValueNumber } from './value-number';
import { ValueString } from './value-string';
import { ValueBoolean } from './value-boolean';
import { ValueEmpty } from './value-empty';
import { ValueError } from './value-error';

@Injectable('Value')
export class Value {
  protected origin: string|number|boolean = null;
  protected actualValue: ActualValue;
  protected position: {row: number, col: number} = {row: -1, col: -1};
  constructor(
    @InjectByName('TableEvent') protected tableEvent: NTableEvent.IDataEvent,
    @InjectFactory() public factory: TFactory
    ) {
    this.actualValue = new ValueEmpty();
  }
  public updatePosition(row: number, col: number) {
    this.position.row = row;
    this.position.col = col;
  }
  public getOriginValue() {
    return this.origin;
  }
  public updateOriginValue(val: string|number|boolean|null) {
    if(!this.actualValue) {
      this.actualValue.destroy();
    }
    if(typeof val === 'string') {
      this.actualValue = this.factory(ValueString);
    } else if(typeof val === 'number') {
      this.actualValue = this.factory(ValueNumber);
    } else if(typeof val === 'boolean') {
      this.actualValue = this.factory(ValueBoolean)
    } else if(val === null || val === undefined) {
      this.actualValue = this.factory(ValueEmpty);
    } else {
      this.actualValue = this.factory(ValueError);
    }
    this.actualValue.update(val);
    if(val !== this.origin) {
      this.tableEvent.tableCellValueChange.next({row: this.position.row, col: this.position.col});
    }
    this.origin = val;
  }
  public getActualValue() {
    return this.actualValue;
  }
  public destroy() {
    this.actualValue.destroy();
  }
}